/*
** get_next_line.c for  in /home/guicqu_g//rush/epikong/etape_1
** 
** Made by gallien guicquero
** Login   <guicqu_g@epitech.net>
** 
** Started on  Fri Mar 25 20:57:38 2011 gallien guicquero
** Last update Sun Mar 27 20:23:54 2011 gallien guicquero
*/

#include	<stdlib.h>
#include	<unistd.h>
#include	"get_next_line.h"

void	*my_malloc(unsigned int size)
{
  void		*p;

  if ((p = malloc(size)) == 0)
    exit(EXIT_FAILURE + 0 * write (2, "Unable to malloc\n", 17));
  return (p);
}

static int	my_strlen(char *s)
{
  int		i;

  i = 0;
  while (s[i] != '\0')
    i = i + 1;
  return (i);
}

static char	*my_strncpy(char *d, char *s, int n)
{
  int   c;

  c = 0;
  while (*s != '\0' && n > 0)
    {
      d[c] = s[c];
      n = n - 1;
      c = c + 1;
    }
  if (c == 0 || n == 0)
    d[c] = '\0';
  return (d);
}

static char	*add_to_line(char *line, int cur, char *buff, int *start)
{
  char		*new_elem;
  int		old_len;

  old_len = (line) ? my_strlen(line) : 0;
  new_elem = my_malloc((old_len + cur + 1) * sizeof(*new_elem));
  my_strncpy(new_elem, line ? line : "", old_len);
  my_strncpy(new_elem + old_len, buff + *start, cur);
  new_elem[old_len + cur] = 0;
  if (line)
    free(line);
  *start += cur + 1;
  return (new_elem);
}

char		*get_next_line(const int fd)
{
  static char	buff[GNL_BUFF_SIZE + 1];
  static int	in_buf = 0;
  static int	start;
  int		cur;
  char		*line;

  line = 0;
  cur = 0;
  while (1)
    {
      if (start >= in_buf)
	{
	  start = 0;
	  if (!(in_buf = read(fd, buff, GNL_BUFF_SIZE)))
	    return (line);
	  if (in_buf == -1)
	    exit(EXIT_FAILURE + 0 * write (2, "Unable to read\n", 15));
	  cur = 0;
	}
      if (buff[start + cur] == '\n')
	return (line = add_to_line(line, cur, buff, &start));
      if (start + cur == in_buf - 1)
	line = add_to_line(line, cur + 1, buff, &start);
      cur++;
    }
}
